package com.luhuiguo.cms.client.presenter;

import java.util.List;

import com.extjs.gxt.ui.client.event.IconButtonEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.ToolButton;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.luhuiguo.cms.client.GlobalConstants;
import com.luhuiguo.cms.client.GlobalMessages;
import com.luhuiguo.cms.shared.event.AddChannelEvent;
import com.luhuiguo.cms.shared.event.ChannelCreatedEvent;
import com.luhuiguo.cms.shared.event.ChannelCreatedEventHandler;
import com.luhuiguo.cms.shared.event.ChannelDeletedEvent;
import com.luhuiguo.cms.shared.event.ChannelDeletedEventHandler;
import com.luhuiguo.cms.shared.event.ChannelUpdatedEvent;
import com.luhuiguo.cms.shared.event.ChannelUpdatedEventHandler;
import com.luhuiguo.cms.shared.event.EditChannelEvent;
import com.luhuiguo.cms.shared.event.LoadArticlesEvent;
import com.luhuiguo.cms.shared.event.LoginEvent;
import com.luhuiguo.cms.shared.event.LoginEventHandler;
import com.luhuiguo.cms.shared.event.RefreshChannelTreeEvent;
import com.luhuiguo.cms.shared.event.RefreshChannelTreeEventHandler;
import com.luhuiguo.cms.shared.model.ChannelModel;
import com.luhuiguo.cms.shared.model.ChannelTreeModel;
import com.luhuiguo.cms.shared.rpc.LoadChannelTree;
import com.luhuiguo.cms.shared.rpc.LoadChannelTreeResult;
import com.luhuiguo.cms.shared.rpc.RemoveChannel;
import com.luhuiguo.cms.shared.rpc.RemoveChannelResult;
import com.luhuiguo.gwt.dispatcher.client.DispatcherAsync;
import com.luhuiguo.gwt.presenter.client.EventBus;
import com.luhuiguo.gwt.presenter.client.widget.WidgetDisplay;
import com.luhuiguo.gwt.presenter.client.widget.WidgetPresenter;

public class ChannelsPresenter extends WidgetPresenter<ChannelsPresenter.Display> {

    public interface Display extends WidgetDisplay {
        void bindTreeItems(List<ChannelTreeModel> roots);

        TreePanel<ChannelTreeModel> getChannelTree();

        MenuItem getAddChannel();

        MenuItem getEditChannel();

        MenuItem getDeleteChannel();

        MenuItem getPreviewChannel();

        ToolButton getRefreshButton();

    }

    private DispatcherAsync dispatcher;

    @SuppressWarnings("unused")
    private GlobalConstants constants;

    private GlobalMessages messages;

    private ChannelTreeModel channelTreeModel;

    @Inject
    public ChannelsPresenter(Display display, EventBus eventBus, DispatcherAsync dispatcher, GlobalConstants constants,
            GlobalMessages messages) {
        super(display, eventBus);

        this.dispatcher = dispatcher;
        this.constants = constants;
        this.messages = messages;
    }

    @Override
    protected void onBind() {
        registerHandler(eventBus.addHandler(LoginEvent.TYPE, new LoginEventHandler() {
            @Override
            public void onLogin(LoginEvent event) {
                loadTreeItems();
            }

        }));

        registerHandler(eventBus.addHandler(RefreshChannelTreeEvent.TYPE, new RefreshChannelTreeEventHandler() {
            @Override
            public void onRefreshChannelTree(RefreshChannelTreeEvent event) {
                loadTreeItems();
            }
        }));

        registerHandler(eventBus.addHandler(ChannelDeletedEvent.TYPE, new ChannelDeletedEventHandler() {

            @Override
            public void onChannelDeleted(ChannelDeletedEvent event) {
                display.getChannelTree().getSelectionModel().selectPrevious();
                display.getChannelTree().getStore().remove(event.getChannelTreeModel());
                Info.display(messages.success(), messages.channelDeleted(event.getChannelTreeModel().getTitle()));

            }
        }));

        registerHandler(eventBus.addHandler(ChannelCreatedEvent.TYPE, new ChannelCreatedEventHandler() {
            @Override
            public void onChannelCreated(ChannelCreatedEvent event) {

                ChannelTreeModel parent = event.getChannelTreeModel();
                ChannelModel m = event.getChannelModel();

                ChannelTreeModel item = new ChannelTreeModel();
                item.setId(m.getId());
                item.setName(m.getName());
                item.setRank(m.getRank());
                item.setTitle(m.getTitle());
                item.setType(m.getType());
                item.setStatus(m.getStatus());

                // ChannelTreeModel parent =
                // display.getChannelTree().getSelectionModel().getSelectedItem();

                if (null != parent) {
                    display.getChannelTree().getStore().add(parent, item, false);
                    display.getChannelTree().setExpanded(parent, true);
                } else {
                    display.getChannelTree().getStore().add(item, false);
                }
                display.getChannelTree().getSelectionModel().select(item, false);
                Info.display(messages.created(), messages.channelCreated(item.getTitle()));

            }

        }));

        registerHandler(eventBus.addHandler(ChannelUpdatedEvent.TYPE, new ChannelUpdatedEventHandler() {
            @Override
            public void onChannelUpdated(ChannelUpdatedEvent event) {
                ChannelTreeModel tm = event.getChannelTreeModel();
                ChannelModel m = event.getChannelModel();

                tm.setName(m.getName());
                tm.setTitle(m.getTitle());
                tm.setType(m.getType());
                tm.setStatus(m.getStatus());

                display.getChannelTree().getStore().update(tm);
                display.getChannelTree().getSelectionModel().deselect(tm);
                display.getChannelTree().getSelectionModel().select(tm, false);
                Info.display(messages.success(), messages.channelUpdated(event.getChannelTreeModel().getTitle()));
            }

        }));

        display.getChannelTree().getSelectionModel().addSelectionChangedListener(
                new SelectionChangedListener<ChannelTreeModel>() {

                    @Override
                    public void selectionChanged(SelectionChangedEvent<ChannelTreeModel> se) {
                        channelTreeModel = se.getSelectedItem();
                        if (null != channelTreeModel) {

                            switch (channelTreeModel.getType()) {
                            case ChannelModel.TYPE_DRAFTS:
                            case ChannelModel.TYPE_TRASH:
                                display.getAddChannel().setEnabled(false);
                                display.getEditChannel().setEnabled(false);
                                display.getDeleteChannel().setEnabled(false);
                                display.getPreviewChannel().setEnabled(false);
                                break;
                            case ChannelModel.TYPE_SITE:
                                display.getAddChannel().setEnabled(true);
                                display.getEditChannel().setEnabled(true);
                                display.getDeleteChannel().setEnabled(false);
                                display.getPreviewChannel().setEnabled(true);

                                break;
                            default:
                                display.getAddChannel().setEnabled(true);
                                display.getEditChannel().setEnabled(true);
                                display.getDeleteChannel().setEnabled(true);
                                display.getPreviewChannel().setEnabled(true);

                                break;

                            }
                            eventBus.fireEvent(new LoadArticlesEvent(channelTreeModel));

                        } else {
                            display.getAddChannel().setEnabled(false);
                            display.getEditChannel().setEnabled(false);
                            display.getDeleteChannel().setEnabled(false);
                            display.getPreviewChannel().setEnabled(false);

                        }

                    }
                });

        display.getRefreshButton().addSelectionListener(new SelectionListener<IconButtonEvent>() {
            @Override
            public void componentSelected(IconButtonEvent ce) {
                eventBus.fireEvent(new RefreshChannelTreeEvent());
            }
        });
        display.getDeleteChannel().addSelectionListener(new SelectionListener<MenuEvent>() {
            @Override
            public void componentSelected(MenuEvent ce) {
                removeChannel();
            }
        });

        display.getAddChannel().addSelectionListener(new SelectionListener<MenuEvent>() {
            @Override
            public void componentSelected(MenuEvent ce) {
                addChannel();
            }
        });

        display.getEditChannel().addSelectionListener(new SelectionListener<MenuEvent>() {
            @Override
            public void componentSelected(MenuEvent ce) {
                editChannel();
            }
        });

        display.getPreviewChannel().addSelectionListener(new SelectionListener<MenuEvent>() {
            @Override
            public void componentSelected(MenuEvent ce) {
                previewChannel();

            }
        });

    }

    protected void previewChannel() {
        final ChannelTreeModel model = display.getChannelTree().getSelectionModel().getSelectedItem();
        if (null != model) {
            String url = "/c-" + model.getId() + ".html";
            Window.open(url, "_blank", "");
        }

    }

    protected void editChannel() {
        final ChannelTreeModel model = display.getChannelTree().getSelectionModel().getSelectedItem();
        if (null != model) {
            eventBus.fireEvent(new EditChannelEvent(model));
        }

    }

    protected void addChannel() {
        final ChannelTreeModel model = display.getChannelTree().getSelectionModel().getSelectedItem();
        // if (null != model) {
        eventBus.fireEvent(new AddChannelEvent(model));
        // }
    }

    protected void removeChannel() {

        final ChannelTreeModel model = display.getChannelTree().getSelectionModel().getSelectedItem();

        final Listener<MessageBoxEvent> l = new Listener<MessageBoxEvent>() {
            public void handleEvent(MessageBoxEvent ce) {
                if (Dialog.YES.equals(ce.getButtonClicked().getItemId())) {
                    doRemoveChannel(model);
                }
            }

        };
        if (null != model) {
            MessageBox.confirm(messages.confirmDelete(), messages.confirmDeleteChannel(model.getTitle()), l);
        }
    }

    private void doRemoveChannel(final ChannelTreeModel channelTreeModel) {
        dispatcher.execute(new RemoveChannel(channelTreeModel.getId()), new AsyncCallback<RemoveChannelResult>() {

            public void onFailure(Throwable caught) {
                MessageBox.alert(messages.error(), messages.deleteChannelFailed(channelTreeModel.getTitle()), null);
            }

            public void onSuccess(RemoveChannelResult result) {
                eventBus.fireEvent(new ChannelDeletedEvent(channelTreeModel));
            }

        });
    }

    @Override
    protected void onRevealDisplay() {

    }

    @Override
    protected void onUnbind() {

    }

    protected void loadTreeItems() {
        GWT.log("loadTreeItems");
        display.getChannelTree().mask();
        dispatcher.execute(new LoadChannelTree(), new AsyncCallback<LoadChannelTreeResult>() {
            @Override
            public void onFailure(Throwable caught) {
                display.getChannelTree().unmask();
                MessageBox.alert(messages.error(), messages.fetchChannelsFailure(), null);
            }

            @Override
            public void onSuccess(LoadChannelTreeResult result) {
                display.getChannelTree().unmask();
                display.bindTreeItems(result.get());
            }

        });
    }
}
